package com.ice.delay.task.core.helper;

import cn.hutool.core.util.ObjectUtil;
import com.ice.delay.task.core.config.DelayTaskConfig;
import com.ice.delay.task.core.enums.ExecuteStatusEnum;
import com.ice.delay.task.core.model.DelayTaskDetail;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 启动服务，加载运行中的任务
 * @author ice
 * @Date 2022/6/4 0004 17:12
 */
@Slf4j
public class TaskInitHelper {
    private static TaskInitHelper instance = new TaskInitHelper();

    public static TaskInitHelper getInstance() {
        return instance;
    }

    private Thread scheduleThread;

    /**
     * 查询运行中的任务，超过执行时间，则立刻执行
     */
    public void start() {
        scheduleThread = new Thread(new Runnable() {
            @Override
            public void run() {
                DelayTaskConfig.getDelayTaskConfig().executeTransaction(() -> {
                    // 获取锁
                    DelayTaskConfig.getDelayTaskConfig().getDelayTaskLockService().selectInitLock();
                    // 查询运行中的任务
                    List<DelayTaskDetail> delayTaskDetails = DelayTaskConfig.getDelayTaskConfig().getDelayTaskDetailService().runingTaskQuery();
                    long now = System.currentTimeMillis();
                    List<DelayTaskDetail> updateTask = new ArrayList<>();
                    for (DelayTaskDetail taskDetail : delayTaskDetails) {
                        if (taskDetail.getNotifyRetryNum() >= DelayTaskConfig.getDelayTaskConfig().getRetryMaxNum()) {
                            // 添加到队列中
                            updateTask.add(taskDetail);
                            continue;
                        }
                        if (now - taskDetail.getNotifyNextTime().getTime() > 0) {
                            // 立刻执行
                            DelayTaskConfig.getDelayTaskConfig().getTaskExecutor().execute(() -> DelayTaskDetailRunnableHelper.execute(taskDetail));
                        } else {
                            // 添加到时间轮中
                            int time = (int) ((taskDetail.getNotifyNextTime().getTime() - now) / 1000);
                            DelayTaskConfig.getDelayTaskConfig().getTimerWheel().addTimerOneTime(time, aVoid -> {
                                // 执行任务
                                DelayTaskDetailRunnableHelper.execute(taskDetail);
                            });
                        }
                    }
                    // 将超过了重试次数的任务停止
                    if (ObjectUtil.isNotEmpty(updateTask)) {
                        List<String> codes = updateTask.stream().map(DelayTaskDetail::getCode).collect(Collectors.toList());
                        DelayTaskConfig.getDelayTaskConfig().getDelayTaskDetailService().batchUpdateExecuteStatus(codes, ExecuteStatusEnum.STOP.getCode());
                    }
                });
            }
        });
        scheduleThread.setName("Task schedule init");
        scheduleThread.start();
    }
}
